const router = require("koa-router")();

router.use("/class/:className", async (ctx, next) => {
  const { className } = ctx.params;

  const classInfo = await BaaS.Models.class
    .query({ where: { baas_id: ctx.baas.id, name: className } })
    .fetch({
      withRelated: ["auth"],
      withRedisKey: ctx.getAppKey(`class:${className}`)
    });
  if (!classInfo) {
    throw new Error(`Class ${className} Unauthorized`);
  }

  // 当前class信息注入ctx
  ctx.class = classInfo;
  // 当前auth信息注入ctx
  ctx.auth = await ctx.checkClassAuth(className);

  await next();
});

router.use("/class/:className/table/:table", async (ctx, next) => {
  const { className, table } = ctx.params;

  // 当前数据表名
  ctx.tableName = table;
  // 数据表访问权限验证
  ctx.classTable = await BaaS.Models.classTable
    .query({
      where: {
        baas_id: ctx.baas.id,
        class_id: ctx.class.id,
        table: table
      }
    })
    .fetch({
      withRelated: ["secret"],
      withRedisKey: ctx.getAppKey(
        `class:${className}:table:${table}:classTable`
      )
    });
  if (!ctx.classTable) {
    ctx.status = 401;
    throw new Error(`Class ${className} Table ${table} Unauthorized`);
  }

  // 当前fields信息注入ctx
  ctx.classFields = await BaaS.Models.classField
    .query({
      where: {
        baas_id: ctx.baas.id,
        class_id: ctx.class.id,
        table: table
      }
    })
    .fetchAll({
      withRedisKey: ctx.getAppKey(
        `class:${className}:table:${table}:classFields`
      )
    });

  // 当前hooks信息注入ctx
  ctx.classHooks = await BaaS.Models.classHook
    .query(qb => {
      qb.where("baas_id", ctx.baas.id);
      qb.where("class_id", ctx.class.id);

      /* eslint-disable */
      qb.where(function() {
        this.where("table", table)
          .orWhere("table", "")
          .orWhereNull("table");
      });
      /* eslint-disable */
    })
    .fetchAll({
      withRedisKey: ctx.getAppKey(
        `class:${className}:table:${table}:classHooks`
      )
    });

  // 运行hook函数
  for (const hook of ctx.classHooks) {
    await ctx.runInVm(hook.body);
  }

  if (ctx.status === 404) {
      await next();
  }
});

module.exports = router;
